package com.xiangxiangjd.controller;

import cn.afterturn.easypoi.word.WordExportUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiangxiangjd.bean.DateNo;
import com.xiangxiangjd.bean.TrUser;
import com.xiangxiangjd.bean.Unit;
import com.xiangxiangjd.bean.vo.InventoryGoods;
import com.xiangxiangjd.bean.xlsx.GetAllGoodsId;
import com.xiangxiangjd.controller.entity.Responsible;
import com.xiangxiangjd.controller.helper.$;
import com.xiangxiangjd.controller.model.ResultModel;
import com.xiangxiangjd.utils.excel.ImportExcel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.xiangxiangjd.bean.result.ResultPage;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ResponseBody;
import com.xiangxiangjd.service.GoodsService;
import com.xiangxiangjd.bean.Goods;
import com.xiangxiangjd.controller.model.ApiResultModel;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.*;

import java.util.stream.Collectors;

/**
 * 物品表 前端控制器
 *
 * @author 肖守凯
 * @since 2021-11-08
 */
@Controller
@RequestMapping("/api/goods")
@Api(tags = "航材仓库")
public class GoodsController extends BaseController {

  // 上传文件大小的上限值
  @Value("${project.resume.max-size}")
  private int resumeMaxSize;

  /**
   * 分页查询Goods
   *
   * @param page 页码
   * @param limit 查几条
   * @param goods 前端传进的参数
   * @return 返回统一分页信息
   */
  @PostMapping(value = "admin/findGoodsByPage")
  @ResponseBody
  @PreAuthorize("hasRole('ROLE_USER')")
  @ApiOperation(value = "退役航材登记申请-分页查询(物品查看)", notes = "退役航材登记申请-分页查询")
  public ResultPage findGoodsByPage(Integer page, Integer limit, Goods goods, DateNo dateNo) {

    if (getUserInfo().getUserAdmin().equals("0")) {
      System.out.println("普通用户");
      dateNo.setUserId(getUserInfo().getId());
    } else {
      dateNo.setUserId("");
    }

    goods.setDateNo(dateNo);

    return goodsService.findGoodsByPage(page, limit, goods);
  }

  /**
   * 分页查询Goods
   *
   * @param page 页码
   * @param limit 查几条
   * @param goods 前端传进的参数
   * @return 返回统一分页信息
   */
  @PostMapping(value = "/getIsGoodsInfo")
  @ResponseBody
  @PreAuthorize("hasRole('ROLE_USER')")
  @ApiOperation(value = "可申领航材信息", notes = "可申领航材信息")
  public ResultPage getIsGoodsInfo(Integer page, Integer limit, Goods goods, DateNo dateNo) {

    //
    //        if (getUserInfo().getUserAdmin().equals("0")) {
    //            System.out.println("普通用户");
    //            dateNo.setUserId(getUserInfo().getId());
    //        } else {
    //            dateNo.setUserId("");
    //        }

    System.out.println(goods);

    dateNo.setUserId(null);
    System.out.println(dateNo);

    goods.setDateNo(dateNo);

    return goodsService.findGoodsByPage(page, limit, goods);
  }

  /**
   * 分页查询Goods
   *
   * @param page 页码
   * @param limit 查几条
   * @param goods 前端传进的参数
   * @return 返回统一分页信息
   */
  @PostMapping(value = "admin/getInventoryInfo")
  @ResponseBody
  @PreAuthorize("hasRole('ROLE_ADMIN')")
  @ApiOperation(value = "盘点查询", notes = "盘点查询")
  public ResultPage getInventoryInfo(
      Integer page,
      Integer limit,
      String userId,
      String unitId,
      String pLiable,
      String purchaseDate,
      String createTime) {

    return goodsService.getInventoryInfo(
        page, limit, userId, unitId, pLiable, purchaseDate, createTime);
  }

  /**
   * 添加Goods
   *
   * @param goods 前端传进的参数
   * @return 返回统一信息
   */
  @PostMapping(value = "admin/addGoods")
  @ResponseBody
  @PreAuthorize("hasRole('ROLE_USER')")
  @ApiOperation(value = "添加详细退役航材（单个）", notes = "添加详细退役航材（单个）")
  public ApiResultModel saveGoods(Goods goods) {

    if (goods.getDateNoId() == null) {
      return $.error("日期单号不可为空");
    }
    return goodsService.addGoods(goods);
  }

  //    /** 编辑Goods
  //     * @param goods  前端传进的参数
  //     * @return 返回统一信息
  //     */
  //    @PostMapping(value = "admin/editGoods")
  //    @ResponseBody
  //    public ApiResultModel editGoods(Goods goods  ){
  //             return goodsService.editGoods(goods);
  //    }

  /**
   * 删除Goods
   *
   * @param ids 前端传进的ID
   * @return 返回统一信息
   */
  @PostMapping(value = "admin/delGoods")
  @ResponseBody
  @PreAuthorize("hasRole('ROLE_USER')")
  @ApiOperation(value = "删除", notes = "删除")
  public ApiResultModel delGoods(@RequestParam("datas") ArrayList ids) {

    return goodsService.delGoodss(ids);
  }

  /** 对在校和在库的对航材和耗材的查询 */
  @PostMapping(value = "airMaterialsInTheLibrary")
  @ResponseBody
  @ApiOperation(value = "在库航材/耗材", notes = "在库航材/耗材")
  @PreAuthorize("hasRole('ROLE_USER')")
  public ResultPage airMaterialsInTheLibrary(@RequestBody Goods goods) {

    Integer page = 1;
    Integer limit = 20;
    // ResultPage data = findGoodsByPage(page, limit, goods);

    //        page = page == null ? 1 : page;
    //        limit = limit == null ? 20 : limit;
    //        LambdaQueryWrapper<Goods> goodsLambdaQueryWrapper = new
    // LambdaQueryWrapper<Goods>().eq(Goods::getUserId, "0").groupBy(Goods::getDateNoId,
    // Goods::getGoodsName, Goods::getModel);
    //
    //
    //        List<Goods> records = goodsService.page(new Page<Goods>(page,
    // limit),goodsLambdaQueryWrapper ).getRecords();
    //
    //        if(goods.getGoodsName().isEmpty()){
    //
    //        }
    //        if(goods.getDateNoId()==null){
    //
    //        }
    //        if(goods.getModel().isEmpty()){
    //
    //        }
    //
    //
    //
    //        int count = goodsService.count(new QueryWrapper<Goods>().select("DISTINCT
    // date_no_id,goods_name,model").lambda().eq(Goods::getUserId, "0"));
    //
    //        ResultPage data=new ResultPage();
    //        data.setCount(count);
    //        data.setMsg("成功");
    //        data.setCode(200);
    //        data.setData(records);

    return null;
  }

  /** 更具订单的id 和 航材名字 查询所有的航材 */
  @PostMapping(value = "/getByAllGoods")
  @ResponseBody
  @ApiOperation(value = "查询航材所有的编号", notes = "查询航材所有的编号")
  @PreAuthorize("hasRole('ROLE_USER')")
  public ResultPage getByAllGoods(
      @RequestParam("dateNoId") Integer dateNoId,
      @RequestParam("goodsName") String goodsName,
      @RequestParam("model") String model,
      Integer page,
      Integer limit) {

    page = page == null ? 1 : page;
    limit = limit == null ? 20 : limit;

    List<Goods> records =
        goodsService
            .page(
                new Page<Goods>(page, limit),
                new LambdaQueryWrapper<Goods>()
                    .eq(Goods::getDateNoId, dateNoId)
                    .eq(Goods::getGoodsName, goodsName)
                    .eq(Goods::getModel, model))
            .getRecords();
    int count =
        goodsService.count(
            new LambdaQueryWrapper<Goods>()
                .eq(Goods::getDateNoId, dateNoId)
                .eq(Goods::getGoodsName, goodsName)
                .eq(Goods::getModel, model));

    ResultPage data = new ResultPage();
    data.setCount(count);
    data.setMsg("成功");
    data.setCode(200);
    data.setData(records);

    return data;
  }

  /** 更具订单的id 和 航材名字 查询所有的航材 */
  @PostMapping(value = "getByUserAllGoods")
  @ResponseBody
  @ApiOperation(value = "查询用户已经有的航材", notes = "查询用户已经有的航材")
  @PreAuthorize("hasRole('ROLE_USER')")
  public ResultPage getByUserAllGoods(
      Goods goods, String purchaseDate, Integer page, Integer limit) {

    page = page == null ? 1 : page;
    limit = limit == null ? 20 : limit;

    goods.setUserId("=" + getUserInfo().getId());

    ResultPage data = goodsService.findByUserAllGoods(goods, purchaseDate, page, limit);

    return data;
  }

  /** 所有的航材 和 所有的耗材登记查看 */
  @PostMapping(value = "getClaimAllGoods")
  @ResponseBody
  @ApiOperation(value = "获取所有申领的物品(更具权限返回数据)", notes = "获取所有申领的物品（更具权限返回数据）")
  @PreAuthorize("hasRole('ROLE_USER')")
  public ResultPage getClaimAllGoods(
      Goods goods, String purchaseDate, Integer page, Integer limit) {

    page = page == null ? 1 : page;
    limit = limit == null ? 20 : limit;

    // 获取当前的用户信息
    TrUser userInfo = getUserInfo();

    String competence = "";

    if (userInfo.getUserAdmin().equals("0")) {
      // 普通用户
      competence = "=" + userInfo.getId();

    } else {
      // 管理员
      competence = "not in ('0','1','2','3')";
    }
    goods.setUserId(competence);

    ResultPage data = goodsService.findByUserAllGoods(goods, purchaseDate, page, limit);

    return data;
  }

  /** 批量设置存放地点 */
  @PostMapping(value = "/admin/setDepositAddress")
  @ResponseBody
  @ApiOperation(value = "批量设置存放地点", notes = "批量设置存放地点", produces = "application/json")
  @PreAuthorize("hasRole('ROLE_USER')")
  public ApiResultModel setDepositAddress(Responsible responsible) {
    boolean update =
        goodsService.update(
            new LambdaUpdateWrapper<Goods>()
                .set(Goods::getDepositAddress, responsible.getUpdateContent())
                .in(Goods::getId, responsible.getIds()));
    if (!update) {
      return $.error("修改失败！");
    }

    return $.success("修改成功！");
  }

  /** 批量设置保管人 */
  @PostMapping(value = "/admin/setPLiable")
  @ResponseBody
  @ApiOperation(value = "批量设置保管人", notes = "批量设置存放地点", produces = "application/json")
  @PreAuthorize("hasRole('ROLE_USER')")
  public ApiResultModel setPLiable(Responsible responsible) {
    boolean update =
        goodsService.update(
            new LambdaUpdateWrapper<Goods>()
                .set(Goods::getPLiable, responsible.getUpdateContent())
                .in(Goods::getId, responsible.getIds()));
    if (!update) {
      return $.error("修改失败！");
    }

    return $.success("修改成功！");
  }

  /** 解析EXCL 比对个人的数据 */
  @PostMapping(value = "import")
  @ApiOperation(value = "盘点数据", notes = "盘点数据", produces = "application/json")
  @PreAuthorize("hasRole('ROLE_USER')")
  @ResponseBody
  public ApiResultModel importFile(
      MultipartFile file,
      String userId,
      String unitId,
      String pLiable,
      String depositAddress,
      String createTime,
      String purchaseDate)
      throws Exception {

    // 检查上传的文件大小
    if (file.getSize() > resumeMaxSize) {

      return $.error("不允许上传超过" + resumeMaxSize / 1024 + "KB的文件");
    }

    //  userId = userId==null?"0":userId;

    // 解析文档
    ImportExcel ei = new ImportExcel(file, 1, 0);

    // 获取第一列数据
    List<GetAllGoodsId> goodsIds = ei.getDataList(GetAllGoodsId.class); // 所属的仓库的物品

    //   盘点的物品编号
    List<String> xlsxGoodsId =
        //  获取所有的id  对重复的id 去重 收集List
        goodsIds.stream().map(GetAllGoodsId::getGoodId).distinct().collect(Collectors.toList());

    System.out.println("******************************");
    System.out.println(xlsxGoodsId);
    System.out.println("******************************");
    // 盘盈和盘中的物品
    List<InventoryGoods> surplusGoods = new ArrayList<>();

    // 单条对比数据库中 输赢
    for (int i = 0; i < xlsxGoodsId.size(); i++) {
      InventoryGoods inventoryGoods = new InventoryGoods();

      // 获取物品   匹配当前物品和 用户的id
      Goods userGoods =
          goodsService.getOne(
              new LambdaQueryWrapper<Goods>()
                  .eq(Goods::getId, xlsxGoodsId.get(i))
                  .eq(Goods::getUserId, userId));

      // 盘盈
      if (userGoods == null) {

        Goods goods =
            goodsService.getOne(
                new LambdaQueryWrapper<Goods>().eq(Goods::getId, xlsxGoodsId.get(i)));

        if (goods == null) {
          inventoryGoods.setId(xlsxGoodsId.get(i));
          inventoryGoods.setGoodsName("该航材不存在 请联系运维人员查看是否已删除");
          inventoryGoods.setModel("该航材不存在 请联系运维人员查看是否已删除");
          inventoryGoods.setCompany("物品不存在");
          inventoryGoods.setSumNumber(0);
          inventoryGoods.setXlsxNumber(1);
          inventoryGoods.setProfit(1);
          inventoryGoods.setDeficit(0);
        }

        inventoryGoods.setId(goods.getId());
        inventoryGoods.setGoodsName(goods.getGoodsName());
        inventoryGoods.setModel(goods.getModel());
        inventoryGoods.setCompany(goods.getCompany());
        inventoryGoods.setSumNumber(0);
        inventoryGoods.setXlsxNumber(1);
        inventoryGoods.setProfit(1);
        inventoryGoods.setDeficit(0);

      } else {
        inventoryGoods.setId(userGoods.getId());
        inventoryGoods.setGoodsName(userGoods.getGoodsName());
        inventoryGoods.setModel(userGoods.getModel());
        inventoryGoods.setCompany(userGoods.getCompany());
        inventoryGoods.setSumNumber(1);
        inventoryGoods.setXlsxNumber(1);
        inventoryGoods.setProfit(0);
        inventoryGoods.setDeficit(0);
      }

      surplusGoods.add(inventoryGoods);
    }
    List<String> unitIds = null;

    if (unitId == null) {

      // unitIds
      List<Unit> subsetAll = unitService.getSubsetAll(unitId);
      unitIds = subsetAll.stream().map(Unit::getId).collect(Collectors.toList());
    }

    // 盘亏  没有盘点物品
    List<Goods> loseMoneyGoods =
        goodsService.loseMoneyGoods(
            userId, unitIds, pLiable, depositAddress, createTime, purchaseDate);

    if (loseMoneyGoods == null) {
      throw new RuntimeException("未找到航材");
    }

    if (loseMoneyGoods.size() > 0) {

      for (int i = 0; i < loseMoneyGoods.size(); i++) {
        // 盘亏物品
        InventoryGoods inventoryGoods = new InventoryGoods();

        inventoryGoods.setId(loseMoneyGoods.get(i).getId());
        inventoryGoods.setGoodsName(loseMoneyGoods.get(i).getGoodsName());
        inventoryGoods.setModel(loseMoneyGoods.get(i).getModel());
        inventoryGoods.setCompany(loseMoneyGoods.get(i).getCompany());
        inventoryGoods.setSumNumber(1);
        inventoryGoods.setXlsxNumber(0);
        inventoryGoods.setProfit(0);
        inventoryGoods.setDeficit(1);
        surplusGoods.add(inventoryGoods);
      }
    }

    Map<String, Object> map = new HashMap();
    // 遍历的对象
    map.put("data", surplusGoods);
    map.put("date", new Date());

    String affiliatedUnits = "库存";

    if (!userId.equals("0")) {
      // 查询单位id
      TrUser user = trUserService.getById(userId);
      //   userId
      Unit unit = unitService.getById(user.getUnitId());

      affiliatedUnits = unit.getUnitName();
    }

    map.put("affiliatedUnits", affiliatedUnits);

    XWPFDocument doc = WordExportUtil.exportWord07("word/InventoryExcel.docx", map);

    // 开始后 Word不可编辑
    doc.enforceReadonlyProtection();

    MultipartFile multipartFile =
        xwpfDocumentToCommonsMultipartFile(doc, System.currentTimeMillis() + ".docx");

    String fileUrl = uploadFile(multipartFile);

    return $.success(200, "成功", fileUrl);
  }

  @GetMapping(value = "/uploadedSuccessfully")
  @ResponseBody
  @PreAuthorize("hasRole('ROLE_USER')")
  @ApiOperation(value = "上传成功 响应码", notes = "上传成功 响应码")
  public ApiResultModel uploadedSuccessfully() {

    return $.success();
  }

  public static void main(String[] args) {
    // Random 随机数工具类 （最小数值为 1）
    Random r = new Random(1);
    // 创建一个布尔类型的数据 长度为20 （注:布尔类型的数组默认值为fales）
    boolean[] b = new boolean[20];
    // 循环参数 i
    int i = 0;
    // 使用do while 循环 进行输出 （第一次必定成功 少判断一次 程序效率更高效）
    do {
      // 随机数 随机整数 最大20
      int random = r.nextInt(20);

      // 利用布尔类型数组下标 判断当前随机数是否为false
      if (b[random] == false) {
        // 如果是是false 修改true
        b[random] = true;
        // 输出1-20  实际为（0-19） 所以++
        random++;
        // 数据分割
        System.out.print(random + ",");
        // 循环条件
        i++;
      } // 序号判断
    } while (i < 20);
  }
}
